/*
 * GwtYuiCarousel - API to integrate YUI Carousel in GWT framework
 *
 * Copyright (c) 2007, Nicolas Hoppenot
 *
 * This free software is licensed under the Apache License, Version 2.0 (the "License").
 * To obtain a copy of the licence, visit : http://www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed WITHOUT ANY WARRANTY OR CONDITION OF ANY KIND.
 * Please see the license for more information.
 *
 * Version $0.6.1-beta1$
 */
package com.gwtyuicarousel.client.util;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Element;

/**
 * Provide util methods to manipulate javascript arrays.
 * 
 * @version $0.6.1-beta1$
 * @author Nicolas Hoppenot
 * 
 */
public class JsArrayUtil {

  /**
   * Shouldn't be instanciated : provide only static util methods
   */
  private JsArrayUtil() {
    // Nothing to do
  }

  /** Create a javascript array. */
  private static native JavaScriptObject createJavaScriptArray() /*-{
    return [];
    }-*/;

  /** Set an Element to the specified index of a javascript array. */
  private static native void setElementInJsArrayIndex(JavaScriptObject jsArray, int index,
      Element element) /*-{
    jsArray[index] = element;
    }-*/;

  /** Remove a single Element at the specified index of a javascript array. */
  private static native void removeElementInJsArray(JavaScriptObject jsArray, int index) /*-{
     jsArray.splice(index, 1);
   }-*/;

  /** Return the length of a javascript array */
  private static native int getJsArrayLength(JavaScriptObject jsArray) /*-{
    return jsArray.length;
    }-*/;

  /** Return the element of a javascript array at the specified index. */
  private static native Element getElementInJsArray(JavaScriptObject jsArray, int index) /*-{
    return jsArray[index];
    }-*/;

  /**
   * Create a gwt array of com.google.gwt.core.client.JavaScriptObject.Element from javascript
   * array. If the javascript array is null, return an ampty gwt array, and not null value.
   * 
   * @param jsArray
   *          The javascript object of element to convert
   * @return The gwt array object
   */
  public static Element[] convertJsToElementArray(JavaScriptObject jsArray) {
    Element[] elements = new Element[getJsArrayLength(jsArray)];
    if (jsArray != null) {
      for (int index = 0; index < elements.length; index++) {
        elements[index] = getElementInJsArray(jsArray, index);
      }
    }
    return elements;
  }

  /**
   * Create a javascript array from a com.google.gwt.core.client.JavaScriptObject.Element gwt array.
   * If the gwt array is null, return an empty javascript object, ans not a null javascript value.
   * 
   * @param elements
   *          The gwt array to convert
   * @return The javascript array object
   */
  public static JavaScriptObject convertElementToJsArray(Element[] elements) {
    JavaScriptObject jsArray = createJavaScriptArray();
    if (elements != null) {
      for (int index = 0; index < elements.length; index++) {
        setElementInJsArrayIndex(jsArray, index, elements[index]);
      }
    }
    return jsArray;
  }

  /**
   * Add an elment to a javascript array.
   * 
   * @param jsArray
   *          The javascript array to which adding a value.
   * @param element
   *          The element to add.
   * @throws NullPointerException
   *           If jsArray Is Null.
   */
  public static void addElementInJsArray(JavaScriptObject jsArray, Element element) {
    if (jsArray == null) {
      throw new NullPointerException("The array to which adding a value shouldn't be null");
    }
    setElementInJsArrayIndex(jsArray, getJsArrayLength(jsArray), element);
  }

  /**
   * Remove the first occurence of an element in a javascript array.
   * 
   * @param jsArray
   *          The javascript array to which adding a value.
   * @param element
   *          The element to remove.
   * @return NullPointerException If jsArray Is Null.
   */
  public static boolean removeElementInJsArray(JavaScriptObject jsArray, Element element) {
    if (jsArray == null) {
      throw new NullPointerException("The array to which removing a value shouldn't be null");
    }
    int jsArrayLen = getJsArrayLength(jsArray);
    for (int index = 0; index < jsArrayLen; index++) {
      if (getElementInJsArray(jsArray, index).equals(element)) {
        removeElementInJsArray(jsArray, index);
        return true;
      }
    }
    return false;
  }

}
